#include "hf_heap.h"
#include "hf_core_common.h"
#include "hf_frame_config.h"


static uint8_t hf_heap[HF_HEAP_SIZE];

/* 静态变量 */
static struct hf_block_link hf_start;           /* 空闲块链表头 */
static struct hf_block_link *hf_end = NULL;     /* 堆末尾标记块 */
static size_t hf_free_bytes = 0;                /* 剩余空闲字节数 */
static const size_t hf_block_header_size = sizeof(struct hf_block_link);



/**
 * hf_heap_init - 初始化内存分配器
 *
 * 设置内存池的初始空闲块，并初始化空闲链表。
 */
void hf_heap_init(void)
{
	struct hf_block_link *first_free;
	uint8_t *aligned_heap;

	/* 确保堆起始地址对齐 */
	aligned_heap = (uint8_t *)hf_align_size((size_t)hf_heap);

	/* 设置堆起始块 */
	hf_start.next_free = (struct hf_block_link *)aligned_heap;
	hf_start.block_size = 0;

	/* 设置堆末尾块 */
	hf_end = (struct hf_block_link *)(aligned_heap + HF_HEAP_SIZE - hf_block_header_size);
	hf_end->block_size = 0;
	hf_end->next_free = NULL;

	/* 初始化第一个空闲块 */
	first_free = (struct hf_block_link *)aligned_heap;
	first_free->block_size = (size_t)(hf_end - first_free);
	first_free->next_free = NULL;

	/* 更新剩余空闲字节数 */
	hf_free_bytes = first_free->block_size;
}

/**
 * hf_malloc - 分配内存
 * @size: 请求的内存大小
 *
 * 返回分配的内存地址，或 NULL（分配失败）。
 */
void *hf_malloc(size_t size)
{
	struct hf_block_link *block, *prev, *new_block;
	void *ret = NULL;

    HF_ENTER_CRITICAL();

	/* 检查请求大小 */
	if (size == 0 || (size + hf_block_header_size) > hf_free_bytes) {
		HF_EXIT_CRITICAL();
        return NULL;
    }

	/* 对齐请求大小 */
	size = hf_align_size(size);

	/* 遍历空闲块，寻找第一个足够大的块 */
	prev = &hf_start;
	block = hf_start.next_free;

	while (block && (block->block_size < (size + hf_block_header_size))) {
		prev = block;
		block = block->next_free;
	}

	/* 未找到合适块 */
	if (!block){
        HF_EXIT_CRITICAL();
        return NULL;
    }

	/* 如果块足够大，尝试分割 */
	if ((block->block_size - size - hf_block_header_size) > hf_block_header_size) {
		new_block = (struct hf_block_link *)((uint8_t *)block + size + hf_block_header_size);
		new_block->block_size = block->block_size - size - hf_block_header_size;
		new_block->next_free = block->next_free;
		block->block_size = size + hf_block_header_size;
		block->next_free = new_block;
	} else {
		/* 从空闲链表移除 */
		prev->next_free = block->next_free;
	}

	/* 更新剩余空闲字节数 */
	hf_free_bytes -= block->block_size;

	/* 返回用户可用地址（跳过头部） */
	ret = (void *)((uint8_t *)block + hf_block_header_size);

    HF_EXIT_CRITICAL();
	return ret;
}

/**
 * hf_free - 释放内存
 * @ptr: 要释放的内存地址
 *
 * 将内存块归还到空闲链表，并尝试合并相邻空闲块。
 */
void hf_free(void *ptr)
{
	struct hf_block_link *block, *iter, *prev;

	if (!ptr)
		return;

    HF_ENTER_CRITICAL();

	/* 获取块头部 */
	block = (struct hf_block_link *)((uint8_t *)ptr - hf_block_header_size);

	/* 更新剩余空闲字节数 */
	hf_free_bytes += block->block_size;

	/* 按地址顺序插入空闲链表 */
	prev = &hf_start;
	iter = hf_start.next_free;

	while (iter && (iter < block)) {
		prev = iter;
		iter = iter->next_free;
	}

	block->next_free = iter;
	prev->next_free = block;

	/* 合并后续块 */
	if ((uint8_t *)block + block->block_size == (uint8_t *)iter) {
		block->block_size += iter->block_size;
		block->next_free = iter->next_free;
	}

	/* 合并前一块 */
	if ((uint8_t *)prev + prev->block_size == (uint8_t *)block) {
		prev->block_size += block->block_size;
		prev->next_free = block->next_free;
	}

    HF_EXIT_CRITICAL();
}

/**
 * hf_get_free_size - 获取剩余空闲内存大小
 *
 * 返回: 剩余空闲字节数
 */
size_t hf_get_free_size(void)
{
	return hf_free_bytes;
}